package com.example.java.concurrent.lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

// ReentrantReadWriteLock 是一个可重入的读写锁，它允许多个线程同时读取共享数据，但在写入时则强制独占访问。这种设计十分适合读多写少的场景，能显著提高性能。
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        Inventory inventory = new Inventory(100); // 初始化库存为100

        // 创建线程来读取库存
        Thread reader1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                int stock = inventory.getStock();
                System.out.println("Reader 1: 当前库存为: " + stock);
                try {
                    Thread.sleep(100); // 模拟读取延迟
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        Thread reader2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                int stock = inventory.getStock();
                System.out.println("Reader 2: 当前库存为: " + stock);
                try {
                    Thread.sleep(150); // 模拟读取延迟
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        // 创建线程来更新库存
        Thread updater1 = new Thread(() -> {
            for (int i = 0; i < 3; i++) {
                inventory.updateStock(-30); // 尝试减少30库存
                try {
                    Thread.sleep(200); // 模拟更新延迟
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        Thread updater2 = new Thread(() -> {
            for (int i = 0; i < 3; i++) {
                inventory.updateStock(20); // 尝试增加20库存
                try {
                    Thread.sleep(250); // 模拟更新延迟
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        // 启动线程
        reader1.start();
        reader2.start();
        updater1.start();
        updater2.start();

        try {
            // 等待线程结束
            reader1.join();
            reader2.join();
            updater1.join();
            updater2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    private static class Inventory {
        private int stock; // 商品库存
        private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

        public Inventory(int initialStock) {
            this.stock = initialStock;
        }

        // 读取库存
        public int getStock() {
            rwLock.readLock().lock(); // 获取读锁
            try {
                return stock;
            } finally {
                rwLock.readLock().unlock(); // 释放读锁
            }
        }

        // 更新库存
        public void updateStock(int amount) {
            rwLock.writeLock().lock(); // 获取写锁
            try {
                if (stock + amount < 0) {
                    System.out.println("库存不足，无法更新库存。");
                } else {
                    stock += amount; // 更新库存
                    System.out.println("库存更新成功，新库存为: " + stock);
                }
            } finally {
                rwLock.writeLock().unlock(); // 释放写锁
            }
        }
    }
}
